#include "Input.h"
#include <stdio.h>

Input::Input(void)
{
	for(int k=0; k<NUMBER_OF_KEYBOARD_KEYS; k++)
	{
		keysLastFrame[k] = false;
		keysThisFrame[k] = false;
	}

	allegroMouseCodes[0] = 1;
	allegroMouseCodes[1] = 2;
	allegroMouseCodes[2] = 4;

	al_get_mouse_state(&mouseStateThisFrame);
	al_get_mouse_state(&mouseStateLastFrame);

	InitJoystickMapping();
}

Input::~Input(void)
{
}

void Input::InitJoystickMapping()
{
	memset(mJoyToKey, 0, sizeof(mJoyToKey));

	mJoyToKey[1] = ALLEGRO_KEY_SPACE;
	mJoyToKey[3] = ALLEGRO_KEY_I;
	mJoyToKey[7] = ALLEGRO_KEY_M;
	mJoyToKey[6] = ALLEGRO_KEY_LCTRL;
}

void Input::ProceedEvent(ALLEGRO_EVENT aEvent)
{
	if(aEvent.type == ALLEGRO_EVENT_KEY_DOWN)
	{
		keysThisFrame[aEvent.keyboard.keycode] = true;
	}
	else if(aEvent.type == ALLEGRO_EVENT_KEY_UP)
	{
		keysThisFrame[aEvent.keyboard.keycode] = false;
	}
	else if (aEvent.type == ALLEGRO_EVENT_JOYSTICK_BUTTON_DOWN)
	{
		keysThisFrame[mJoyToKey[aEvent.joystick.button]] = true;
	}
	else if (aEvent.type == ALLEGRO_EVENT_JOYSTICK_BUTTON_UP)
	{
		keysThisFrame[mJoyToKey[aEvent.joystick.button]] = false;
	}
	else if (aEvent.type == ALLEGRO_EVENT_JOYSTICK_AXIS)
	{
		/// Movement
		if (aEvent.joystick.stick == 2)
		{
			if (aEvent.joystick.axis == 1)
			{
				if (aEvent.joystick.pos > 0.1f)
					keysThisFrame[ALLEGRO_KEY_S] = true;
				else if (aEvent.joystick.pos < -0.1f)
					keysThisFrame[ALLEGRO_KEY_W] = true;
				else
				{
					keysThisFrame[ALLEGRO_KEY_S] = false;
					keysThisFrame[ALLEGRO_KEY_W] = false;
				}
			} else if (aEvent.joystick.axis == 0)
			{
				if (aEvent.joystick.pos > 0.1f)
					keysThisFrame[ALLEGRO_KEY_D] = true;
				else if (aEvent.joystick.pos < -0.1f)
					keysThisFrame[ALLEGRO_KEY_A] = true;
				else
				{
					keysThisFrame[ALLEGRO_KEY_A] = false;
					keysThisFrame[ALLEGRO_KEY_D] = false;
				}
			}
		} else if (aEvent.joystick.stick == 1)
		{
			if (aEvent.joystick.axis == 0)
			{
				if (aEvent.joystick.pos > 0.1f)
					keysThisFrame[ALLEGRO_KEY_DOWN] = true;
				else if (aEvent.joystick.pos < -0.1f)
					keysThisFrame[ALLEGRO_KEY_UP] = true;
				else
				{
					keysThisFrame[ALLEGRO_KEY_UP] = false;
					keysThisFrame[ALLEGRO_KEY_DOWN] = false;
				}
			}
		} else if (aEvent.joystick.stick == 0)
		{
			if (aEvent.joystick.axis == 2)
			{
				if (aEvent.joystick.pos > 0.1f)
					keysThisFrame[ALLEGRO_KEY_RIGHT] = true;
				else if (aEvent.joystick.pos < -0.1f)
					keysThisFrame[ALLEGRO_KEY_LEFT] = true;
				else
				{
					keysThisFrame[ALLEGRO_KEY_RIGHT] = false;
					keysThisFrame[ALLEGRO_KEY_LEFT] = false;
				}
			}
		}
	}
	else if (aEvent.type == ALLEGRO_EVENT_JOYSTICK_CONFIGURATION)
	{
		al_reconfigure_joysticks();
	}
	else if(aEvent.type == ALLEGRO_EVENT_MOUSE_AXES ||
					aEvent.type == ALLEGRO_EVENT_MOUSE_ENTER_DISPLAY ||
					aEvent.type == ALLEGRO_EVENT_MOUSE_BUTTON_DOWN ||
					aEvent.type == ALLEGRO_EVENT_MOUSE_BUTTON_UP)
	{
		al_get_mouse_state(&mouseStateThisFrame);
  }
}

bool Input::KeyPressed(int aKey)
{
	return (keysThisFrame[aKey] && !keysLastFrame[aKey]);
}

bool Input::KeyDown(int aKey)
{
	return (keysThisFrame[aKey] && keysLastFrame[aKey]);
}

bool Input::KeyReleased(int aKey)
{
	return (!keysThisFrame[aKey] && keysLastFrame[aKey]);
}

bool Input::MousePressed(int aKey)
{
	return ((mouseStateThisFrame.buttons & allegroMouseCodes[aKey]) && 
				 !(mouseStateLastFrame.buttons & allegroMouseCodes[aKey]));
}

bool Input::MouseDown(int aKey)
{
	return ((mouseStateThisFrame.buttons & allegroMouseCodes[aKey]) && 
				  (mouseStateLastFrame.buttons & allegroMouseCodes[aKey]));
}

bool Input::MouseReleased(int aKey)
{
	return (!(mouseStateThisFrame.buttons & allegroMouseCodes[aKey]) && 
				   (mouseStateLastFrame.buttons & allegroMouseCodes[aKey]));
}

int Input::MouseDraggedX()
{
	return mouseStateThisFrame.x - mouseStateLastFrame.x;
}

int Input::MouseDraggedY()
{
	return mouseStateThisFrame.y - mouseStateLastFrame.y;
}

int Input::MouseScrolled()
{
	return mouseStateThisFrame.z - mouseStateLastFrame.z;
}

int Input::GetMouseX()
{
	return mouseStateThisFrame.x;
}

int Input::GetMouseY()
{
	return mouseStateThisFrame.y;
}

int Input::GetMouseZ()
{
	return mouseStateThisFrame.z;
}

void Input::Tick()
{
	for(int k=0; k<NUMBER_OF_KEYBOARD_KEYS; k++)
	{
		keysLastFrame[k] = keysThisFrame[k];
	}

	mouseStateLastFrame = mouseStateThisFrame;
}